package Datatypes;

import Interfaces.IPerfil;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "nodo", propOrder = {
    
    "valor",
    "objeto"
    
})
public class Nodo extends DefaultMutableTreeNode implements Serializable{

    private static final long serialVersionUID = 1L;
    private Object valor = null;
    private Object objeto = null;

    public Nodo() {}
    
    public Nodo(String titulo, Object valor) {

        super(titulo);
        this.valor = valor;

    }

    public Object getValor() {

        return this.valor;

    }

    public Object getObjeto(){
    
        return this.objeto;
    
    }
    
    public void setValor(Object valor) {

        this.valor = valor;

    }

    public void setObjeto(Object objeto){
    
        this.objeto = objeto;
    
    }
    
    public Boolean existeNodo(Nodo n) {

        Boolean existe = false;

        if (this.valor.equals(n.getValor())) {

            existe = true;

        } 
        
        else {

            Enumeration<Nodo> hijos = this.children();

            while ((hijos.hasMoreElements()) && (existe == false)) {

                existe = hijos.nextElement().existeNodo(n);

            }

        }

        return existe;

    }

    public Boolean existeNodo(Object valor) {

        Boolean existe = false;

        if (this.valor.equals(valor)) {

            existe = true;

        } 
        
        else {

            Enumeration<Nodo> hijos = this.children();

            while ((hijos.hasMoreElements()) && (existe == false)) {

                existe = hijos.nextElement().existeNodo(valor);

            }

        }

        return existe;

    }

    public void insertarNodo(Nodo n) {

        add(n);

    }

    public void insertarNodo(Nodo n, Nodo padre) {

        if (existeNodo(padre)) {

            if (padre.getValor().equals(this.valor)) {

                insertarNodo(n);

            } 
            
            else {

                Enumeration<Nodo> hijos = this.children();

                while (hijos.hasMoreElements()) {

                    hijos.nextElement().insertarNodo(n, padre);

                }

            }

        }

    }

    public void insertarNodo(Nodo n, Object padre) {

        if (existeNodo(padre)) {

            if (padre.equals(this.valor)) {

                insertarNodo(n);

            } 
            
            else {

                Enumeration<Nodo> hijos = this.children();

                while (hijos.hasMoreElements()) {

                    hijos.nextElement().insertarNodo(n, padre);

                }

            }

        }

    }

    public void mostrarNodo() {

        System.out.println(this.valor);

        Enumeration<Nodo> hijos = this.children();

        while (hijos.hasMoreElements()) {

            hijos.nextElement().mostrarNodo();

        }

    }

    public List<Nodo> listarNodos() {

        List<Nodo> lista = new ArrayList();

        Enumeration<Nodo> hijos = this.children();

        while (hijos.hasMoreElements()) {

            lista = hijos.nextElement().listarNodos();

        }

        lista.add(0, this);

        return lista;

    }
    
    public String listarNodosHTML(IPerfil ip, Boolean cargarImagen) throws Exception{

        String nodos;
        
        if(this instanceof NodoRoot){
        
            nodos = "<ul id = '" + valor.toString() + "' name = '" + valor.toString() + "'></ul>";
        
        }
        
        else{
            
            DataComentario dc = (DataComentario) objeto;
            DataPerfil dp = ip.obtenerPerfil(dc.getCliente(), false);
            String imagen = dp.getImagen();
            
            nodos = "<ul class = 'comentario' id = '" + valor.toString() + "' name = '" + valor.toString() + "'>"
            + "<br><div class = 'puntajes' id = 'DIV_Puntaje" + valor.toString() + "'></div><label class = 'imagenPerfil' id = 'IMG_ImagenPerfil" + valor.toString() + "'><img id = 'IMG_ImagenPerfil' src = '" + imagen + "'></label>" + "<br><label class = 'tituloComentario'><label class = 'nickCliente'>" + dc.getCliente() + "</label> dice:</label><br>" 
            + "<label class = 'fechaComentario'>" + dc.getFecha().getString() + "</label><br><br>"
            + "<div class = 'contenidoComentario' id = 'texto" + valor.toString() +"' name = 'texto" + valor.toString() +"'>" 
            + dc.getTexto() + "<br><button id = 'BTN_Respuesta" + valor.toString() + "' class = 'respuesta' type = 'button' onclick = 'mostrarRespuesta(event);'>Responder</button></div><br>";

        }
            
        Enumeration<Nodo> hijos = this.children();

        while (hijos.hasMoreElements()) {

            nodos = nodos + hijos.nextElement().listarNodosHTML(ip, cargarImagen);

        }

        nodos = nodos + "</ul>";

        return nodos;

    }

    public void borrarNodo(Object valor) {

        if (this.valor.equals(valor)) {

            this.removeFromParent();

        } 
        
        else {

            Enumeration<Nodo> hijos = this.children();

            while (hijos.hasMoreElements()) {

                hijos.nextElement().borrarNodo(valor);

            }

        }

    }

    public void borrarNodo(Nodo n) {

        if (this.equals(n)) {

            this.removeFromParent();

        } 
        
        else {

            Enumeration<Nodo> hijos = this.children();

            while (hijos.hasMoreElements()) {

                hijos.nextElement().borrarNodo(n);

            }

        }

    }

    public Nodo buscarNodo(Object valor) {

        Nodo buscado = null;

        if (existeNodo(valor)) {

            if (this.valor.equals(valor)) {

                buscado = this;

            } 
            
            else {

                Enumeration<Nodo> hijos = this.children();

                while (hijos.hasMoreElements() && (buscado == null)) {

                    buscado = hijos.nextElement().buscarNodo(valor);

                }

            }

        }

        return buscado;

    }
}
